
package primitives;

import static de.berlin.fu.inf.nbi.rdflinda.Constants.*;

import java.io.File;
import java.util.Arrays;

import org.nlogo.api.*;

/**
 * @author Daniel Graff Is responsible for generating file names.
 */
public class FilenameGeneration
extends AbstractCustomReporter
{

    /**
     * Returns the syntax for NetLogo. The primitive takes one number as input and returns a string.
     * 
     * @return Returns a list for input and output
     */
    @Override
    public Syntax getSyntax() {
        return Syntax.reporterSyntax(new int[] { Syntax.TYPE_NUMBER }, Syntax.TYPE_STRING);
    }

    /**
     * Returns a specific file name attached with a serial number.
     * 
     * @param args
     *            The arguments
     * @param arg1
     *            The context
     * @return Returns the file name
     * @throws ExtensionException
     *             The exception
     * @throws LogoException
     */
    public Object report(Argument args[], Context arg1)
    throws ExtensionException, LogoException {

        logger.debug("Start primitive FilenameGeneration...");
        final int size = args[0].getIntValue();
        final String plotDirName = getAlphabeticName(size) + PLOTS_BASE_DIR_NAME_FOR_FAILURES;
        final File plotDirFile = new File(NETLOGO_PLOTS_STORAGE_BASE_PATH + "\\" + plotDirName);

        logger.debug("Got input parameter '" + size + "'");
        logger.debug("Computed plotDirName '" + plotDirFile.getPath() + "'");

        createDirIfNotExist(plotDirFile);

        return getNewFilename(plotDirFile);
    }

    /**
     * Creates the directory if it does not exist
     * 
     * @param pDir
     *            The directory
     * @throws ExtensionException
     *             The exception
     */
    private void createDirIfNotExist(File pDir)
    throws ExtensionException {
        if (!pDir.exists()) {
            logger.debug("'" + pDir.getPath() + "' doesn't exists. Create it ...");
            if (!pDir.mkdirs())
                throw new ExtensionException("createDir: couldn't create dir");
            try {
                Thread.sleep(500);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Converts a number into a string representation.
     * 
     * @param pNumber
     *            The number
     * @return Returns the string
     * @throws ExtensionException
     *             The exception
     */
    private String getAlphabeticName(int pNumber)
    throws ExtensionException {
        switch (pNumber) {
            case 0:
                return "no";
            case 1:
                return "one";
            case 2:
                return "two";
            case 3:
                return "three";
            case 4:
                return "four";
            default:
                throw new ExtensionException("'" + pNumber + "' is not supported yet!");
        }
    }

    /**
     * Obtains the new file name in the given directory
     * 
     * @param pDir
     *            The directory
     * @return Returns the new file name
     */
    private String getNewFilename(File pDir) {
        logger.debug("trying to determine new filename...");
        String result = TEST_FILENAME;

        String[] files = pDir.list();

        // handling empty arrays...
        if (files.length == 0) {
            result += START_NUMBER;
            logger.debug("Currently there are no files..\r\nResult is '" + result + "'");
        }
        else {

            // sort is ascending; with it the biggest element is the last one
            Arrays.sort(files);

            String last = files[files.length - 1];

            int serialNumber = Integer.parseInt(last.substring(last.indexOf('_') + 1, last
                .indexOf('.')));

            result += ++serialNumber;
            logger.debug("Currently there are " + files.length + " file(s).." + "\r\nResult is '"
                + result + "'");
        }

        return pDir.getAbsolutePath() + "\\" + result;
    }
}
